package com.example.springsidedevelop.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;


import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
public class AsyncCallConfig {
    private static final Logger log = LoggerFactory.getLogger(AsyncCallConfig.class);

    @Autowired
    private TaskThreadPoolConfig taskThreadPoolConfig;

    /**
     * 自定义异步线程池
     * @return
     */
    @Bean
    public AsyncTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setThreadNamePrefix("MyExecutor-");
        executor.setMaxPoolSize(taskThreadPoolConfig.getMaxPoolSize());
        executor.setCorePoolSize(taskThreadPoolConfig.getCorePoolSize());
        executor.setQueueCapacity(taskThreadPoolConfig.getQueueCapacity());
        executor.setKeepAliveSeconds(taskThreadPoolConfig.getKeepAliveSeconds());

        // 设置拒绝策略
        /**
         * 当Executor已经关闭（即执行了executorService.shutdown()方法后），并且Executor将有限边界用于最大线程数量和工作队列容量，
         * 且已经饱和时，在方法execute()中提交的新任务将被拒绝。
         * 预定义的处理程序策略：
         * (1) 默认的ThreadPoolExecutor.AbortPolicy   处理程序遭到拒绝将抛出运行时RejectedExecutionException;
         * (2) ThreadPoolExecutor.CallerRunsPolicy 线程调用运行该任务的 execute 本身。此策略提供简单的反馈控制机制，能够减缓新任务的提交速度
         * (3) ThreadPoolExecutor.DiscardPolicy  不能执行的任务将被删除;
         * (4) ThreadPoolExecutor.DiscardOldestPolicy  如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）。
         * 这四个RejectedExecutionHandler的实现类都是ThreadPoolExecutor的静态内部类。
         * 线程池默认会采用的是defaultHandler策略
         *
         */
        /*executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                // .....
            }
        });*/
        // 使用预定义的异常处理类
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }


}
